package com.sloera.java.common.tool.config;

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.sloera.java.common.tool.jackson.SloeraJavaTimeModule;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.text.SimpleDateFormat;
import java.util.TimeZone;

/**
 * @author liuwangyang
 * @version 1.0
 * @class com.sloera.java.common.tool.config.JacksonConfiguration
 * @date 2020-8-7
 */
@Configuration
@ConditionalOnClass(ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonConfiguration {

    //两种方式都可以，暂未知区别
    /*@Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        // 忽略json字符串中不识别的属性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                // 忽略无法转换的对象 “No serializer found for class com.xxx.xxx”
                .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
                // NULL不参与序列化
                //    objectMapper.setSerializationInclusion(Include.NON_NULL);
                // PrettyPrinter 格式化输出
                .configure(SerializationFeature.INDENT_OUTPUT, true)
                // 指定时区，默认 UTC，而不是 jvm 默认时区
                .setTimeZone(TimeZone.getTimeZone("GMT+8:00"))
                // 日期类型处理
                .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).findAndRegisterModules()
                // Java8日期类型处理
                .registerModule(new SloeraJavaTimeModule())
                .findAndRegisterModules()
                // 单引号处理
                .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
                //空字段处理
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        converter.setObjectMapper(objectMapper);
        //处理指定格式
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        return converter;
    }*/
    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        // 忽略json字符串中不识别的属性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                // 忽略无法转换的对象 “No serializer found for class com.xxx.xxx”
                .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
                // NULL不参与序列化
                //    objectMapper.setSerializationInclusion(Include.NON_NULL);
                // PrettyPrinter 格式化输出
                .configure(SerializationFeature.INDENT_OUTPUT, true)
                // 指定时区，默认 UTC，而不是 jvm 默认时区
                .setTimeZone(TimeZone.getTimeZone("GMT+8:00"))
                // 日期类型处理
                .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).findAndRegisterModules()
                // Java8日期类型处理
                .registerModule(new SloeraJavaTimeModule()).findAndRegisterModules()
                // 单引号处理
                .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
                //空字段处理
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return objectMapper;
    }

}
